<template>
  <el-form
    ref="ruleFormRef"
    :model="form"
    :rules="rules"
    label-width="0"
    size="large"
    @keyup.enter="login(ruleFormRef)"
  >
    <el-form-item prop="username">
      <el-input
        v-model="form.username"
        prefix-icon="user"
        clearable
        placeholder="请输入"
      ></el-input>
    </el-form-item>

    <el-form-item prop="password">
      <el-input
        v-model="form.password"
        prefix-icon="lock"
        clearable
        show-password
        placeholder="请输入"
      ></el-input>
    </el-form-item>

    <el-form-item>
      <div class="boxCode">
        <el-input
          v-model="form.captcha"
          prefix-icon="CircleCheck"
          clearable
          placeholder="请输入验证码"
        ></el-input>
        <el-image :src="captchaUrl" @click="getImage" class="code"></el-image>
      </div>
    </el-form-item>

    <div class="rememberMe">
      <div>
        <el-checkbox
          label="记住密码"
          v-model="memoryPassword"
          @change="onMemoPassword"
        />
      </div>
      <div>
        <router-link to="/reset_password">忘记密码？</router-link>
      </div>
    </div>

    <el-form-item>
      <el-button
        type="primary"
        style="width: 100%"
        round
        @click="login(ruleFormRef)"
      >
        登录
      </el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import {
  reactive,
  ref,
  onBeforeMount,
  getCurrentInstance,
  ComponentInternalInstance,
  Ref,
} from 'vue'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { captchaImage, loginByJson } from '@api/login'
import { Encrypt, Decrypt } from '@utils/aes'
import { UserRuleForm } from '@interface/login'
import useLogin from '@hooks/useLogin'
import useMemoPassword from '@hooks/useMemoPassword'

const { proxy } = getCurrentInstance() as ComponentInternalInstance

let captchaUrl = ref<string>('')

const ruleFormRef = ref<FormInstance>()
let rules = reactive<FormRules<UserRuleForm>>({})

const form = reactive<UserRuleForm>({
  username: '',
  password: '',
  captcha: '',
  key: '',
})

let getImage = async () => {
  const key: string = new Date().getTime().toString()
  form.key = key
  const res = await captchaImage({ key })
  let blob = new Blob([res], { type: 'image/png' })
  let imgUrl = URL.createObjectURL(blob)
  captchaUrl.value = imgUrl
}

onBeforeMount(() => {
  let userPwd: string | null = localStorage.getItem('user-pwd')
  if (userPwd) {
    let { username, password }: { username: string; password: string } =
      JSON.parse(userPwd)
    form.username = Decrypt(username)
    form.password = Decrypt(password)
  }
  rules = {
    username: [{ required: true, message: '正确用户名', trigger: 'blur' }],
    password: [{ required: true, message: '正确密码', trigger: 'blur' }],
  }
  getImage()
})

const login = async (formEl: FormInstance | any) => {
  if (!formEl) return
  await formEl.validate(async (valid) => {
    if (valid) {
      let res = await loginByJson({
        username: Encrypt(form.username),
        password: Encrypt(form.password),
        key: form.key,
        captcha: form.captcha,
      })

      useLogin(res)
      // 本地记住密码
      setMemoPassword()
    } else {
      return ElMessage.warning('请填写正确内容')
    }
    return
  })
}

// 记住密码
const { onMemoPassword, memoVal } = useMemoPassword()
const memoryPassword: Ref<boolean> = ref(memoVal)
const setMemoPassword = () => {
  if (memoryPassword.value) {
    const userPwd: {
      username: string
      password: string
    } = {
      username: Encrypt(form.username) as string,
      password: Encrypt(form.password) as string,
    }
    localStorage.setItem('user-pwd', JSON.stringify(userPwd))
  } else {
    localStorage.removeItem('user-pwd')
  }
}
</script>

<style scoped>
.boxCode {
  display: flex;
  align-items: center;
  width: 100%;
}
.code {
  margin-left: 10px;
  height: 40px;
  width: 100px;
  cursor: pointer;
}
.rememberMe {
  font-size: 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}
</style>
